/*
 * Copyright 2017-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *     http://aws.amazon.com/apache2.0/
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package com.amazon.aace.vehicle.config;

import com.amazon.aace.core.config.EngineConfiguration;

/**
 * The @c VehicleConfiguration class is a factory interface for creating "aace.vehicle" configuration objects.
 */
public class VehicleConfiguration {

    /**
     * Specifies the vehicle properties required in configuration
     */
    public enum VehiclePropertyType {
        /**
         * The make of the vehicle.
         * 
         * @hideinitializer
         */
        MAKE("MAKE","make"),

        /**
         * The model of the vehicle.
         * 
         * @hideinitializer
         */
        MODEL("MODEL","model"),

        /**
         * The model year of the vehicle.
         * A value of this property type must be an integer in the range 1900-2100.
         * Example value: "2019"
         * 
         * @hideinitializer
         */
        YEAR("YEAR","year"),

        /**
         * The trim level of the vehicle, identifying the vehicle's level of equipment or special features.
         * Example values: "Standard", "Sport", "Limited"
         * 
         * @hideinitializer
         */
        TRIM("TRIM","trim"),

        /**
         * The current location (country/region/state/etc.) of the vehicle. 
         * Example values: "US", "US-North", "WA"
         * 
         * @hideinitializer
         */
        GEOGRAPHY("GEOGRAPHY","geography"),

        /**
         * The client software version.
         * Example value: "2.2.1X"
         * 
         * @hideinitializer
         */
        VERSION("VERSION","version"),

        /**
         * The operating system used by the vehicle's infotainment system.
         * Example value: "AndroidOreo_8.1"
         * 
         * @hideinitializer
         */
        OPERATING_SYSTEM("OPERATING_SYSTEM","os"),

        /**
         * The hardware architecture used by the vehicle.
         * Example value: "x86_64"
         * 
         * @hideinitializer
         */
        HARDWARE_ARCH("HARDWARE_ARCH","arch"),

        /**
         * The language or locale selected for Alexa by the vehicle owner.
         * Example values: "en-US", "fr-CA"
         * 
         * @hideinitializer
         */
        LANGUAGE("LANGUAGE","language"),

        /**
         * The type and arrangement of microphone used by the vehicle.
         * Example value: "7 mic array, centrally mounted"
         * 
         * @hideinitializer
         */
        MICROPHONE("MICROPHONE","microphone"),

        /**
         * A comma-separated list of supported countries (ISO country codes).
         * Example value: "US,CA"
         * 
         * @hideinitializer
         */
        COUNTRY_LIST("COUNTRY_LIST","countries"),

        /**
         * The automaker's identifier for the vehicle.
         * 
         * @hideinitializer
         */
        VEHICLE_IDENTIFIER("VEHICLE_IDENTIFIER","vehicleIdentifier");

        /**
         * @internal
         */
        private String mName;

        /**
         * @internal
         */
        private String mKey;

        /**
         * Type used to identify a vehicle property type and value pair
         */
        VehiclePropertyType( String name, String key ) {
            mName = name;
            mKey = key;
        }

        /**
         * @internal
         */
        public String toString() {
            return mName;
        }

        /**
         * @internal
         */
        public String getKey() {
            return mKey;
        }
    }

    public static class VehicleProperty {
        private VehiclePropertyType mType;
        private String mValue;

        public VehicleProperty( VehiclePropertyType type, String value ) {
            mType = type;
            mValue = value;
        }

        public VehiclePropertyType getType() { return mType; }
        public String getValue() { return mValue; }
    }

    /**
     * Factory method used to programmatically generate "aace.vehicle" vehicle info configuration data.
     * The data generated by this method is equivalent to providing the following JSON
     * values in a configuration file:
     *
     * @code{.json}
     * {
     *   "aace.vehicle":
     *   {
     *      "info": {
     *          "make": "<MAKE>",
     *          "model": "<MODEL>",
     *          "year": "<YEAR>",
     *          "trim": "<TRIM>",
     *          "geography": "<GEOGRAPHY>",
     *          "version": "<SOFTWARE_VERSION>",
     *          "os": "<OPERATING_SYSTEM>",
     *          "arch": "<HARDWARE_ARCH>",
     *          "language": "<LANGUAGE>",
     *          "microphone": "<MICROPHONE>",
     *          "countries": "<COUNTRY_LIST>",
     *          "vehicleIdentifier": "<VEHICLE_IDENTIFIER>"
     *      }
     *   }
     * }
     * @endcode
     *
     * @param propertyList A list of @c VehicleProperty type and value pairs
     */
    public static EngineConfiguration createVehicleInfoConfig( final VehicleProperty[] propertyList )
    {
        return new EngineConfiguration() {
            @Override
            protected long createNativeRef() {
                return createVehicleInfoConfigBinder( propertyList );
            }
        };
    }

    /**
     * Factory method used to programmatically generate vehicle operating country configuration data.
     * The data generated by this method is equivalent to providing the following JSON
     * values in a configuration file:
     *
     * @code{.json}
     * {
     *   "aace.vehicle": {
     *      "operatingCountry": "<COUNTRY>"
     *   }
     * }
     * @endcode
     *
     * @param operatingCountry A 2-letter ISO country code
     */
    public static EngineConfiguration createOperatingCountryConfig( final String operatingCountry )
    {
        return new EngineConfiguration() {
            @Override
            protected long createNativeRef() {
                return createOperatingCountryConfigBinder( operatingCountry );
            }
        };
    }

    // Native Engine JNI methods
    static private native long createVehicleInfoConfigBinder( VehicleProperty[] propertyList );
    static private native long createOperatingCountryConfigBinder( String operatingCountry );
}
